package com.yuncheng.spcyApi.flowService;

import com.yuncheng.entity.YcSysUser;
import com.yuncheng.vo.GetKsKz;
import com.yuncheng.vo.CurrentUserVo;
import org.apache.commons.collections.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yuncheng.spcyApi.busService.BusService;
import com.yuncheng.spcyApi.constant.common.LogConstant;
import com.yuncheng.spcyApi.constant.flow.RckpConstant;
import com.yuncheng.spcyApi.constant.common.SpcyConstant;
import com.yuncheng.spcyApi.entity.*;
import com.yuncheng.spcyApi.service.ISpcyLogService;
import com.yuncheng.spcyApi.service.ISpcySqsxBaiscService;
import com.yuncheng.spcyApi.service.ISpcySqsxJobService;
import com.yuncheng.spcyApi.service.ISysUserFgldService;
import com.yuncheng.spcyApi.service.impl.YcSysUserServiceImpl;
import com.yuncheng.spcyApi.utils.GetCurrentUserUtils;

import com.yuncheng.spcyApi.vo.common.Result;
import com.yuncheng.spcyApi.vo.flow.AgentVo;
import com.yuncheng.spcyApi.vo.flow.YpscFlowVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import utils.DateConversionUtils;
import utils.LogUtils;
import utils.ObjectToMapUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Component(value = "rckpFlowService")
public class RckpFlowService extends FlowService  {
    private static final Logger log = LoggerFactory.getLogger(RckpFlowService.class);

    @Resource
    @Lazy
    private RckpConstant flowConstant;

    @Resource
    @Lazy
    private ISpcySqsxJobService spcySqsxJobService;

    @Resource
    @Lazy
    private ISysUserFgldService sysUserFgldService;

    @Resource
    @Lazy
    private YcSysUserServiceImpl ycSysUserService;

    @Resource
    @Lazy
    private ISpcySqsxBaiscService spcySqsxBaiscService;

    @Resource
    @Lazy
    private BusService busService;

    @Resource
    @Lazy
    private ISpcyLogService spcyLogService;

    /**
     * 获取当前流程任务相关信息
     * @param jobid 流程任务id
     */
    public Map getJobConcernByJobId(String jobid){
        Map map = new HashMap();

        // 当前流转记录
        SpcySqsxJob job = spcySqsxJobService.getById(jobid);
        if (job == null){
            log.error("当前流程任务id为【{}】的流转记录不存在",jobid);
            return map;
        }
        String sqsxid = job.getFpid();
        if (org.apache.commons.lang3.StringUtils.isBlank(sqsxid)){
            log.error("当前流程任务id为【{}】的流转记录中的申请事项id为空",jobid);
            return map;
        }

        // 申请事项基本信息
        SpcySqsxBasic sqsxBasic = spcySqsxBaiscService.getById(sqsxid);

        // 流程任务流传记录
        List<String> nodeList = Arrays.asList(RckpConstant.NODENAME.split(",")); // 所有环节名称
        LambdaQueryWrapper<SpcySqsxJob> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SpcySqsxJob::getFpid, sqsxid);
        queryWrapper.in(SpcySqsxJob::getFhjmc,nodeList);
        queryWrapper.orderByAsc(SpcySqsxJob::getFfssj);
        queryWrapper.orderByAsc(SpcySqsxJob::getCreateTime);
        List<SpcySqsxJob> jobList = spcySqsxJobService.list(queryWrapper);

        // 申请事项相关文件记录
        List<SpcySqsxWjjl> wjjlList = busService.getWjjlListBySqsxId(sqsxid);

        // 申请事项的缺陷检查项目
        List<SpcySqsxJcxm> jcxmList = busService.getJcxmQxListBySqsxId(sqsxBasic);

        // 申请事项的选派记录-查验-同意选派
        List<SpcySqsxXpjl> cyxpjlList = busService.getTyXpXpjlList(sqsxid,SpcyConstant.FLOW_TYPE_CY);
        List<SpcySqsxXpjl> hcyXpjlList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(cyxpjlList)){
            hcyXpjlList = cyxpjlList.stream().filter(
                    x -> StringUtils.isNotBlank(x.getFssk()) && !x.getFssk().equals(SpcyConstant.HCY_SSK_YB))
                    .collect(Collectors.toList());
        }

        // 获取下环节待办人
        Map nextDbr = getNextDbr(sqsxid, jobid);
        String nextNode = nextDbr.get("nextNode").toString();
        List<AgentVo> dbrListByMap = busService.getDbrListByMap(nextDbr);

        map.put("sqsx",sqsxBasic); // 申请事项基本信息
        map.put("job",job); // 当前流转记录
        map.put("jobHistoryList",jobList); // 流程任务流传记录
        map.put("wjjlList",wjjlList); // 申请事项-相关文件
        map.put("qxjcxmList",jcxmList); // 申请事项-检查项目
        map.put("cyxpjlList",hcyXpjlList); // 申请事项-选派记录-查验
        map.put("nextNodeDbrList",dbrListByMap); // 下环节待办人list
        map.put("nextNode",nextNode);

        return map;
    }

    /**
     * 获取当前日常考评相关信息
     * @param jobid 流程任务id
     */
    public Map getRckpxxByJobId(String jobid){
        Map map = new HashMap();

        // 当前流转记录
        SpcySqsxJob job = spcySqsxJobService.getById(jobid);
        if (job == null){
            log.error("当前流程任务id为【{}】的流转记录不存在",jobid);
            return map;
        }
        String sqsxid = job.getFpid();
        if (org.apache.commons.lang3.StringUtils.isBlank(sqsxid)){
            log.error("当前流程任务id为【{}】的流转记录中的申请事项id为空",jobid);
            return map;
        }

        // 申请事项基本信息
        SpcySqsxBasic sqsxBasic = spcySqsxBaiscService.getById(sqsxid);

        // 申请事项的选派记录-查验-同意选派
        List<SpcySqsxXpjl> cyxpjlList = busService.getTyXpXpjlList(sqsxid,SpcyConstant.FLOW_TYPE_CY);
        List<SpcySqsxXpjl> hcyXpjlList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(cyxpjlList)){
            hcyXpjlList = cyxpjlList.stream().filter(
                    x -> StringUtils.isNotBlank(x.getFssk()) && !x.getFssk().contains(SpcyConstant.HCY_SSK_YB))
                    .collect(Collectors.toList());
        }

        map.put("sqsx",sqsxBasic); // 申请事项基本信息
        map.put("job",job); // 当前流转记录
        map.put("cyxpjlList",hcyXpjlList); // 申请事项-选派记录-查验

        return map;
    }

    /**
     * 获取下环节待办人
     * @param sqsxid 申请事项id
     */
    public Map getNextDbr(String sqsxid,String jobid){
        String jobNodeName = busService.getJobNodeName(jobid); // 获取当前流程任务job环节

        // 下一个环节名称
        String nextNodeName = flowConstant.getNextNodeName(jobNodeName);
        Map nodeDbr = new HashMap();
        nodeDbr = getNodeDbr(sqsxid, nextNodeName, "");

        nodeDbr.put("nextNode",nextNodeName);

        return nodeDbr;
    }

    public Result handleFlow(YpscFlowVo ypscFlowVo, SpcySqsxJob nowJob, String jobId, String sqsxid, String submitType, String opinion){
        // 当前流程任务
        if (StringUtils.isNotBlank(jobId)) {
            nowJob = spcySqsxJobService.getById(jobId);
        }

        if (nowJob == null){
            return Result.error("当前流程任务不存在，请重试");
        }

        // 提交按钮
        if (submitType.equals(RckpConstant.SUBMIT_TYPE_SUBMIT)) {
            if (nowJob == null) {
                return Result.error("当前流程任务不存在");
            }
        }
        CurrentUserVo currentUser = GetCurrentUserUtils.getCurrentUser();
        if (currentUser == null){
            return Result.error("登录已失效，请重新登录");
        }

        // 待审核任务
        if (nowJob.getFhjmc().equals(RckpConstant.HJMC_DSHRW)) {
            SpcySqsxBasic sqsx = spcySqsxBaiscService.getById(sqsxid);
            if (sqsx != null){
                sqsx.setFrckpdshblr(currentUser.getName());
                sqsx.setFrckpdshblrid(currentUser.getId());
                spcySqsxBaiscService.updateById(sqsx);
            }

            // 流程环节处理
            Result httpResult = handleNodeName(ypscFlowVo, submitType, nowJob, sqsxid, opinion);
            if (!httpResult.isSuccess()){
                return httpResult;
            }
        }else if (nowJob.getFhjmc().equals(RckpConstant.HJMC_DFHRW)) {
            // 待复核任务
            SpcySqsxBasic sqsx = spcySqsxBaiscService.getById(sqsxid);
            if (sqsx != null){
                sqsx.setFrckpdfhblr(currentUser.getName());
                sqsx.setFrckpdfhblrid(currentUser.getId());
                spcySqsxBaiscService.updateById(sqsx);
            }

            Result httpResult = handleNodeName(ypscFlowVo, submitType, nowJob, sqsxid, opinion);
            if (!httpResult.isSuccess()){
                return httpResult;
            }
        }else if (nowJob.getFhjmc().equals(RckpConstant.HJMC_DSPRW)) {
            // 待审批任务
            SpcySqsxBasic sqsx = spcySqsxBaiscService.getById(sqsxid);
            if (sqsx != null){
                sqsx.setFrckpdspblr(currentUser.getName());
                sqsx.setFrckpdspblrid(currentUser.getId());
                spcySqsxBaiscService.updateById(sqsx);
            }

            Result httpResult = handleNodeName(ypscFlowVo, submitType, nowJob, sqsxid, opinion);
            if (!httpResult.isSuccess()){
                return httpResult;
            }

            // 计算日常考评结果
            List<SpcySqsxXpjl> xpjlList = busService.getTyXpXpjlList(sqsxid, SpcyConstant.FLOW_TYPE_CY);
            String frckpjg = "";
            if (CollectionUtils.isNotEmpty(xpjlList)) {
                for (SpcySqsxXpjl xpjl : xpjlList) {
                    if (StringUtils.isNotBlank(xpjl.getFzhpj())) {
                        frckpjg += xpjl.getFjcyxm() + ":" + xpjl.getFzhpj() + "; ";
                    }else {
                        frckpjg += xpjl.getFjcyxm() + ": 未填写。";
                    }
                }
            }
            if (sqsx != null){
                sqsx.setFrckpjg(frckpjg);
                sqsx.setFrckpsj(new Date());
                spcySqsxBaiscService.updateById(sqsx);
            }
        }else {
            // 已完成考评任务
            Result httpResult = handleNodeName(ypscFlowVo, submitType, nowJob, sqsxid, opinion);
            if (!httpResult.isSuccess()){
                return httpResult;
            }
        }

        return Result.ok("操作成功");
    }

    public Result handleNodeName(YpscFlowVo ypscFlowVo,String submitType, SpcySqsxJob job, String sqsxId, String opinion){
        HashMap<String, Object> map = ypscFlowVo.getMap();
        String dbrid = ypscFlowVo.getDbrid();// 下环节待办人
        String smgflag = ypscFlowVo.getSmgflag(); // 短信发送标志
        boolean isSubmit = true; // 是否提交流程
        Result res = null;

        // 保存按钮
        if (submitType.equals(RckpConstant.SUBMIT_TYPE_SAVE)){

        }

        // 提交按钮
        if (submitType.equals(RckpConstant.SUBMIT_TYPE_SUBMIT)){

            // 流程任务id
            String jobId = "";
            if (job != null){
                jobId = job.getId();
            }

            String jobNodeName = busService.getJobNodeName(jobId); // 获取环节名称

            // 待审批任务
            if (StringUtils.isNotBlank(jobNodeName) && jobNodeName.equals(RckpConstant.HJMC_DSPRW)){
              /*  isSubmit = false;
                CurrentUserVo currentUser = GetCurrentUserUtils.getCurrentUser();
                if (currentUser == null){
                    return Result.error("登录已失效，请重新登录");
                }
                Result result = this.doJob(job, currentUser, opinion);
                if (!result.isSuccess()){
                    return Result.error(result.getMessage());
                }*/
                smgflag = "否";
            }

            // 提交流程任务,待办人是否为空，指定待办人
            if (isSubmit) {
                if (StringUtils.isBlank(dbrid)) {
                    // 提交-流程任务
                    res = this.passJob(sqsxId, jobId, opinion, "", "");
                } else {
                    // 提交-流程任务
                    res = this.passJob(sqsxId, jobId, opinion, "", dbrid);
                }
            }
            if (!res.isSuccess()){
                return res;
            }else {
                SpcySqsxJob nowJob = (SpcySqsxJob)res.getResult();
                // 接收返回的流程任务，如果返回的流程任务id不相等，发送短信
                if (nowJob != null && !jobId.equals(nowJob.getId()) && StringUtils.isNotBlank(smgflag) && smgflag.equals("是")){
                    busService.sendSmsToPassJob(nowJob);
                }
            }
        }

        return Result.ok("提交成功");
    }

    //初始化任务
    public Result initJob(String sqsxId, CurrentUserVo currentUser){
        String nodeName = flowConstant.getFirstNode();
        //需要校验是否已经初始化过
        List<SpcySqsxJob> list = spcySqsxJobService.list(new LambdaQueryWrapper<SpcySqsxJob>()
                .eq(SpcySqsxJob::getFpid, sqsxId)
                .eq(SpcySqsxJob::getFhjmc, nodeName)
                .eq(SpcySqsxJob::getFlcmc, flowConstant.getFlowName())
        );

        if(list.size()>0){
            log.error("已经初始化过日常考评流程：申请事项id【{}】", sqsxId);
            /*List<String> ids = list.stream().map(SpcySqsxJob::getId).collect(Collectors.toList());
            spcySqsxJobService.removeBatchByIds(ids);*/
            return Result.ok("操作成功");
        }
        return this.createNextJob(flowConstant,sqsxId,null,currentUser,nodeName,"");
    }

    /**
     * 提交当前环节的待办记录
     *  @param sqsxId 申请事项id
     *  @param jobId 当前环节id
     *  @param opinion 办理意见
     */
    public Result passJob(String sqsxId, String jobId, String opinion,String nextNodeName,String nextNodeDbrIds){
        //处理业务表的逻辑
        Result httpResult = this.passJob(flowConstant, sqsxId, jobId, opinion, nextNodeName, nextNodeDbrIds);
        return httpResult;
    }

    /** 办理流程 */
    private Result doJob(SpcySqsxJob job, CurrentUserVo currentUser, String opinion){
        String blrId = "";
        String blr = "";
        if (currentUser != null) {
            blrId = currentUser.getId();
            blr = currentUser.getName();
        }
        if (job == null){
            return Result.error("当前流程任务不存在，请重试");
        }
        if(SpcyConstant.BLZT_YB.equals(job.getFblzt())){
            return Result.error("当前任务已提交");
        }
        if(StringUtils.isBlank(job.getFdbrid())){
            return Result.error("当前任务未指定办理人");
        }
        if(!job.getFdbrid().contains(blrId)){
            return Result.error("当前登录用户无此任务的办理权限");
        }
        // 办理方式 竞争办理 、多人线性办理 、多人并行办理
        String blfs = job.getFblfs();
        if(StringUtils.isBlank(blfs)||blfs.equals(SpcyConstant.BLFS_DRJJ)){
            job.setFblr(blr);
            job.setFblsj(new Date());
            job.setFblyj(opinion);
            job.setFblzt(SpcyConstant.BLZT_YB);
            spcySqsxJobService.updateById(job);
            return Result.ok(job);
        }else if(blfs.equals(SpcyConstant.BLFS_DRXX)  || blfs.equals(SpcyConstant.BLFS_DRBX)){
            //先根据多个人线性和多人并行的逻辑获得下一办理人
            String nextBlrId ="";
            String nextBlr ="";
            if(blfs.equals(SpcyConstant.BLFS_DRXX)){
                String ydbrIds[] = job.getFydbrid().split(",");
                String ydbrs[] = job.getFydbr().split(",");
                for (int i=0;i<ydbrIds.length;i++){
                    String dbrId = ydbrIds[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if(dbrId.equals(blrId)){
                        if(i+1<ydbrIds.length){
                            nextBlrId=ydbrIds[i+1];
                            nextBlr=ydbrs[i+1];
                            break;
                        }
                    }
                }
            }else{
                String dbrIds[] = job.getFdbrid().split(",");
                String dbrs[] = job.getFdbr().split(",");
                for (int i=0;i<dbrIds.length;i++){
                    String dbrId = dbrIds[i];
                    String dbr = dbrs[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if(!dbrId.equals(blrId)){
                        nextBlrId=nextBlrId+(StringUtils.isBlank(nextBlrId)?"":",")+dbrId;
                        nextBlr=nextBlr+(StringUtils.isBlank(nextBlr)?"":",")+dbr;
                    }
                }
            }

            //如果存在下一办理人 就继续待办，多人办理意见用@@分隔，办理时间、办理人、意见 用|分隔
            job.setFblr(blr);
            job.setFblsj(new Date());
            String blyj=(job.getFblyj()==null?"":job.getFblyj())+(StringUtils.isBlank(job.getFblyj())?"":"@@")+ DateConversionUtils.DateToString(new Date()) +"|"+blr+"|"+ opinion;
            job.setFblyj(blyj);
            if(StringUtils.isBlank(nextBlrId)){
                job.setFblzt(SpcyConstant.BLZT_YB);
            }else{
                job.setFblzt(SpcyConstant.BLZT_DB);
                job.setFdbrid(nextBlrId);
                job.setFdbr(nextBlr);
            }
            spcySqsxJobService.updateById(job);
            return Result.ok(job);
        }
        return Result.error("待办任务未指定办理方式");
    }

    // 获取当前环节待办人
    public Map getNodeDbr(String sqsxid, String nodeName, String dbrIds){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";
        if(StringUtils.isNotBlank(dbrIds)){
            dbr = getDbrsByIds(dbrIds);
            dbrId = dbrIds;
        }else{
            SpcySqsxBasic sqsx = spcySqsxBaiscService.getById(sqsxid);
            String dept = "";
            if (sqsx != null && StringUtils.isNotBlank(sqsx.getFywflcode())){
                dept = SpcyConstant.getYwclNameByCode(sqsx.getFywflcode());
            }
            // 待审核日常考评
            if (nodeName.equals(RckpConstant.HJMC_DSHRW)){
                // 主办人
                Map zbrMap = getZbrBySqsxId(sqsxid);
                dbrId = zbrMap.get("dbrId").toString();
                dbr = zbrMap.get("dbr").toString();
            }

            // 待复核日常考评
            if (nodeName.equals(RckpConstant.HJMC_DFHRW)){
                // 科室负责人
                Map kzMap = getKsfzrByDeptName(dept);
                dbrId = kzMap.get("dbrId").toString();
                dbr = kzMap.get("dbr").toString();
            }

            // 待审批日常考评
            if (nodeName.equals(RckpConstant.HJMC_DSPRW)){
                // 分管领导
                Map kzMap = getKsFgldByDeptName(dept);
                dbrId = kzMap.get("dbrId").toString();
                dbr = kzMap.get("dbr").toString();
            }

            // 已完成日常考评
            if (nodeName.equals(RckpConstant.HJMC_YWCKPRW)) {
                // 分管领导
//                dbrId = "";
//                dbr = "";
                Map kzMap = getKsFgldByDeptName(dept);
                dbrId = kzMap.get("dbrId").toString();
                dbr = kzMap.get("dbr").toString();
            }
        }

        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }

    // 获取当前环节待办人
    public Map getNodeDbr(String nodeName, String dbrIds){
        return this.getNodeDbr(null,nodeName,dbrIds);
    }

    // 根据待办人id，获取名称拼接起来
    private String getDbrsByIds(String dbrIds){
        //把待办人按id查出来  把名字拼起来
        String dbr = "";
        List<String> dbrIdsList = Arrays.asList(dbrIds.split(","));
        List<YcSysUser> sysUserList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(dbrIdsList)){
            sysUserList = ycSysUserService.listByIds(dbrIdsList);
        }

        if (CollectionUtils.isNotEmpty(sysUserList)){
            for (YcSysUser user : sysUserList){
                dbr += user.getRealname() + ",";
            }
        }

        return dbr;
    }

    // 对应科室的 科室负责人
    public Map getKsfzrByDeptName(String deptName){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";
        List<GetKsKz> ksKzObject = new ArrayList<>();
        ksKzObject = ycSysUserService.getKsKzObject(deptName, SpcyConstant.GW_NAME_KZ);
        if (CollectionUtils.isNotEmpty(ksKzObject)) {
            for (GetKsKz ksKz : ksKzObject) {
                dbrId += ksKz.getId()+",";
                dbr += ksKz.getRealname()+",";
            }
        }

        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }

    // 获取对应科室的 分管领导
    public Map getKsFgldByDeptName(String deptName){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";

        YcSysUser fgldUserBydept = sysUserFgldService.getFgldUserBydept(deptName);
        if (fgldUserBydept != null) {
            dbrId = fgldUserBydept.getId();
            dbr = fgldUserBydept.getRealname();
        }

        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }

    // 获取主办人
    public Map getZbrBySqsxId(String sqsxId){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";

        SpcySqsxBasic basic = spcySqsxBaiscService.getById(sqsxId);
        if (basic != null && StringUtils.isNotBlank(basic.getFzbr())){
            List<String> userids = Arrays.asList(basic.getFzbr().split(",|，"));
            if (CollectionUtils.isNotEmpty(userids)) {
                for (String uid : userids) {
                    YcSysUser sysUser = ycSysUserService.getById(uid);
                    if (sysUser != null) {
                        if (StringUtils.isBlank(dbrId)) {
                            dbrId += sysUser.getId();
                            dbr += sysUser.getRealname();
                        } else {
                            dbrId += "," + sysUser.getId();
                            dbr += "," + sysUser.getRealname();
                        }
                    }
                }
            }
        }

        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }

    // 退回流程
    public Result getReturnUpperFlowJob(String jobid,String opinion){
        if (StringUtils.isBlank(jobid)){
            return Result.error("当前流程任务id不能为空");
        }
        SpcySqsxJob job = spcySqsxJobService.getById(jobid);
        if (job == null){
            return Result.error("当前流程任务不存在");
        }
        // 办理状态 - 待办
        if (StringUtils.isNotBlank(job.getFblzt()) && (job.getFblzt().equals(SpcyConstant.BLZT_DB) || job.getFblzt().equals(SpcyConstant.BLZT_TH))){
            // 待办-获取上一个环节id
            String fsyhjid = job.getFsyhjid();
            SpcySqsxJob syhjJob = spcySqsxJobService.getById(fsyhjid);
            if (syhjJob != null){
                syhjJob.setFthyj(opinion);
                syhjJob.setFfssj(new Date());
                syhjJob.setFblzt(SpcyConstant.BLZT_TH);
                spcySqsxJobService.updateById(syhjJob);

                spcySqsxJobService.removeById(jobid); // 删除当前流程任务待办
            }
        }

        String logNr = "退回上一环节: ";
        Map<String, Object> map = ObjectToMapUtils.objectToMap(job);
        logNr += LogUtils.MapToStringMethod(map);
        spcyLogService.addLogs(job.getFhjmc(),logNr,job.getFpid(), LogConstant.LOGS_SQSX_JOB,SpcyConstant.LOGS_SYS_TYPE_TH);
        return Result.ok("success");
    }
}
